package com.takeshi.landlords.config;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.takeshi.landlords.entity.ChannelGroupObj;
import com.takeshi.landlords.entity.GamePlayer;
import com.takeshi.landlords.util.CardModel;
import com.takeshi.landlords.util.DoubleList;
import com.takeshi.landlords.util.UserState;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.spi.LocaleServiceProvider;
import java.util.stream.Collectors;

/**
 * 发牌者
 *
 * @author Nanase Takeshi
 * @date 2022/2/16 9:21
 */
@Slf4j
@Service
public class Dealer {

    public static final int COLOR_COUNT = 4;
    public static final String SUN = "S";
    public static final String MOON = "M";
    public static final String[] POKER_NUMBERS = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};
    /**
     * 比较大小的顺序
     */
    public static final List<String> COMPARATOR_POKER_ORDER = Arrays.asList("3", "4", "5", "6", "7", "8", "9", "0", "J", "Q", "K", "A", "2", "M", "S");
    public static final List<String> FULL_POKER_ORDER = Arrays.asList("S", "M", "2", "A", "K", "Q", "J", "0", "9", "8", "7", "6", "5", "4", "3");
    /**
     * 手牌展示的顺序
     */
    public static final List<String> SHOW_FULL_POKER_ORDER = Arrays.asList("S", "M", "2", "A", "K", "Q", "J", "10", "9", "8", "7", "6", "5", "4", "3");

    public static final String STRAIGHT_STR = "AKQJ09876543";
    public static final String PAIR_STR = "AAKKQQJJ0099887766554433";
    public static final String AIRPLANE_STR = "AAAKKKQQQJJJ000999888777666555444333";
    public static final List<String> LIST = new ArrayList<>();

    static {
        if (CollUtil.isEmpty(LIST)) {
            synchronized (LocaleServiceProvider.class) {
                if (CollUtil.isEmpty(LIST)) {
                    for (String pokerNumber : POKER_NUMBERS) {
                        for (int i = 0; i < COLOR_COUNT; i++) {
                            LIST.add(pokerNumber);
                        }
                    }
                    LIST.add(SUN);
                    LIST.add(MOON);
                }
            }
        }
    }

    /**
     * 给房间内用户分配手牌
     *
     * @param channelGroupObj
     */
    public static void deal(ChannelGroupObj channelGroupObj) {
        //洗牌
        Collections.shuffle(LIST);
        //保存三张底牌
        channelGroupObj.setHoleCard(LIST.stream().limit(3).collect(Collectors.toList()));
        List<String> list = LIST.stream().skip(3).collect(Collectors.toList());
        DoubleList<GamePlayer> userList = channelGroupObj.getUserList();
        int max = userList.size();
        for (int i = 0; i < max; i++) {
            ArrayList<String> arrayList = new ArrayList<>();
            for (int j = 0; j < (list.size() / max); j++) {
                arrayList.add(list.get(j * max + i));
            }
            //手牌排序
            arrayList.sort(Comparator.comparing(SHOW_FULL_POKER_ORDER::indexOf));
            //将用户状态设置成发牌后选举地主
            GamePlayer gamePlayer = userList.get(i);
            gamePlayer.setHandCardList(arrayList).setState(UserState.CHOOSE_LANDLORD.getState());
            Optional.ofNullable(channelGroupObj.getChannelGroup().find(gamePlayer.getChannelId())).map(item -> item.write(new TextWebSocketFrame(StrUtil.format("[{}] hand cards is [{}]", gamePlayer.getNickname(), String.join(StrUtil.SPACE, gamePlayer.getHandCardList())))));
        }
        channelGroupObj.getChannelGroup().flush();
    }

    /**
     * 转成list且排序
     *
     * @param content
     * @return
     */
    @SuppressWarnings("all")
    public static List<String> toList(String content) {
        ArrayList<String> list = new ArrayList<>();
        char[] charArray = content.toUpperCase(Locale.ROOT).toCharArray();
        Map<String, Integer> map = new HashMap<>(charArray.length << 1);
        for (char c : charArray) {
            String value = String.valueOf(c);
            map.compute(value, (k, v) -> ObjectUtil.isNull(v) ? 0 : v + 1);
            list.add(value);
        }
        //排序
        list.sort(Comparator.comparing(map::get).reversed().thenComparing(FULL_POKER_ORDER::indexOf));
        return list;
    }

    /**
     * 比较当前出的牌是否大过上一个有效的牌
     *
     * @param currentCardModel 当前的牌型
     * @param lastCardModel    上一个有效的牌型
     * @param currentCard      当前牌
     * @param lastCard         上一个有效牌
     * @return
     */
    public static boolean isBiggerCard(List<String> handCardList, CardModel currentCardModel, CardModel lastCardModel, List<String> currentCard, List<String> lastCard) {
        String current = currentCard.get(0).toUpperCase(Locale.ROOT);
        String last = lastCard.get(0).toUpperCase(Locale.ROOT);
        //比较牌型
        if (!lastCardModel.equals(CardModel.BOMB) && currentCardModel.equals(CardModel.BOMB)) {
            //四个的炸弹
            return true;
        }
        if (lastCardModel.equals(CardModel.BOMB) && currentCardModel.equals(CardModel.BOMB)) {
            //四个的炸弹
            return COMPARATOR_POKER_ORDER.indexOf(current) > COMPARATOR_POKER_ORDER.indexOf(last);
        }
        //去掉当前出的牌剩余的牌数
        long remainingCount = handCardList.stream().filter(item -> !currentCard.contains(item)).count();
        if (lastCardModel.equalsAny(CardModel.THREE_IDENTICAL_CARDS, CardModel.THREE_BELT_ONE, CardModel.THREE_BELT_PAIR) && currentCardModel.equals(CardModel.THREE_IDENTICAL_CARDS) && NumberUtil.equals(remainingCount, 0L)) {
            //如果当前用户手中的牌只剩下三张相同的牌（三不带）时可以管上上一个有效牌是三张相同的牌（三不带）|三带一|三带一对的
            return COMPARATOR_POKER_ORDER.indexOf(current) > COMPARATOR_POKER_ORDER.indexOf(last);
        }
        if (!lastCardModel.equals(currentCardModel)) {
            //当前出的牌型与上一个有效牌型不符
            return false;
        }
        if (lastCardModel.equalsAny(CardModel.LEAFLET, CardModel.PAIR, CardModel.STRAIGHT_PATTERN, CardModel.PAIR_PATTERN, CardModel.AIRPLANE_PATTERN, CardModel.AIRCRAFT_WITH_SINGLE_CARD_PATTERN, CardModel.AIRPLANE_WITH_PAIR_PATTERN) && lastCard.size() == currentCard.size()) {
            //单张|对子|顺子|连对|飞机不带翅膀|飞机带翅膀（带单张）|飞机带翅膀（带对子）
            return COMPARATOR_POKER_ORDER.indexOf(current) > COMPARATOR_POKER_ORDER.indexOf(last);
        }
        if (lastCardModel.equalsAny(CardModel.THREE_IDENTICAL_CARDS, CardModel.THREE_BELT_ONE, CardModel.THREE_BELT_PAIR, CardModel.FOUR_WITH_TWO, CardModel.FOUR_WITH_TWO_PAIRS)) {
            //三张相同的牌（三不带）|三带一|三带一对|四带两张|四带两对
            return COMPARATOR_POKER_ORDER.indexOf(current) > COMPARATOR_POKER_ORDER.indexOf(last);
        }
        return false;
    }

}
